<?php

/*
 * CopyRight  : (C)2012-2099 HaoTeam Inc.
 * Document   : Auth.php
 * Created on : 2020-7-25 9:45:58
 * Author     : Tiger <1192851302@qq.com>
 * Description: This is NOT a freeware, use is subject to license terms.
 *              这即使是一个免费软件,使用时也请遵守许可证条款,得到当时人书面许可.
 *              未经书面许可,不得翻版,翻版必究;版权归属 HaoTeam Inc;
 */

namespace app\admin\controller;

use app\Request;
use haoteam\service\UtilService;
use haoteam\service\SessionService;
use haoteam\service\SmsService;
use haoteam\http\validates\AdminUserValidate;
use app\admin\model\AdminActionLog;
use app\admin\model\AdminUserToken;
use app\admin\model\AdminUser;
use app\admin\model\AdminUserLogin;
use think\facade\Cache;
use think\facade\Session;
use think\facade\Db;

/**
 * 管理鉴权
 * Class Auth
 * Tiger <1192851302@qq.com> 2020-7-25 9:45:58
 */
class Auth {

    /**
     * 登录
     * @author Tiger <1192851302@qq.com>
     * @param Request $request
     * @return type
     */
    public function login(Request $request) {
        [$account, $password] = UtilService::postMore([
                    'account',
                    'password'
                        ], $request, true);
        $user = AdminUser::where('username|mobile|email', $account)->find();
        //加入登录限制
        if (empty($user->username)) {
            return app('json')->fail('账号不存在');
        }
        if (empty($user->password)) {
            return app('json')->fail('账号或密码错误');
        }
        $checkCount = AdminUserLogin::user_logincheck($user->username);
        if ($checkCount <= 0) {
            return app('json')->fail('你已经被锁定,15分钟之后在试');
        }
        if ($user->password !== encrypt_password($password, $user->salt)) {
            return app('json')->fail('账号或密码错误，' . $checkCount . '次后将被锁定');
        }
        if ($user->state == 0) {
            return app('json')->fail('已被禁止，请联系管理员');
        }
        //组合一些信息
        $user->levelName = Db::name('admin_user_level')->where('id', $user->level)->value('title');
        $user->rolesName = Db::name('admin_user_role')->where('id', $user->roles)->value('title');
        /**
         * 加入节点权限
         * 当权限赋予每个人的时候有效
         */
        $nodes = Db::name('admin_user_node')->where('uid', $user->id)->column('node') ?? [];
        if (empty($nodes)) {
            /**
             * 加入节点权限
             * 当权限赋予某一个角色组时有效
             */
            $nodes = Db::name('admin_user_role_node')->where('role_id', $user->roles)->column('node') ?? [];
        }
        try {
            $token = AdminUserToken::createToken($user, 'admin');
        } catch (\Exception $exc) {
            return app('json')->fail($exc->getMessage());
        }

        //写入服务器Session
        Session::set('token', $token->token);
        //写入系统Session
        SessionService::instance()->set(compact('user', 'nodes'), $token->token);
        //写入操作日志
        AdminActionLog::_write('系统用户登录', '登录系统后台成功');
        return app('json')->successful('登录成功', ['data' => SessionService::instance()->online_data, 'token' => $token->token, 'expires_time' => $token->expires_time]);
    }

    /**
     * 短信验证码
     * @author Tiger <1192851302@qq.com>
     * @param Request $request
     * @return type
     */
    public function sms_code(Request $request) {
        list($phone, $type) = UtilService::postMore([['phone', 0], ['type', '']], $request, true);
        if (preg_match("/^1[3-9]\d{9}$/", $phone) === false) {
            return app('json')->fail('手机号不正确');
        }

        if (AdminUser::be(['mobile' => $phone]) && $type == 'register') {
            return app('json')->fail('手机号已注册');
        }
        if (AdminUser::be(['mobile' => $phone]) <= 0 && $type == 'login') {
            return app('json')->fail('账号不存在！');
        }
        $time = 60;
        if (Cache::get('code_' . $phone)) {
            return app('json')->fail($time . '秒内有效');
        }
        $code = rand(100000, 999999);
        $res = SmsService::send($phone, SmsService::VERIFICATION_CODE, compact('code', 'time'));
        if ($res['status'] == 400) {
            return app('json')->fail('短信平台验证码发送失败' . $res['msg']);
        }
        Cache::set('code_' . $phone, $code, $time);
        return app('json')->successful($res['msg'] ?? '发送失败');
    }

    /**
     * 注册用户
     * @author Tiger <1192851302@qq.com>
     * @return type
     */
    public function register() {
        $post = UtilService::postMore([
                    'username',
                    'mobile',
                    'vercode',
                    'password',
                    'repassword'
        ]);
        $validate = new AdminUserValidate();
        if ($validate->scene('register')->check($post) == false) {
            return app('json')->fail($validate->getError());
        }
        $post['roles'] = 3; //注册用户全部安排到临时角色
        $post['salt'] = create_salt();
        $post['password'] = encrypt_password($post['password'], $post['salt']);
        $verifyCode = Cache::get('code_' . $post['mobile']);
        if (empty($verifyCode)) {
            return app('json')->fail('请先获取验证码');
        }
        if (substr($verifyCode, 0, 6) != $post['vercode']) {
            return app('json')->fail('验证码错误');
        }

        try {
            AdminUser::create($post);
        } catch (\Exception $exc) {
            return app('json')->fail($exc->getMessage());
        }

        return app('json')->successful('注册成功');
    }

    /**
     * 重置密码
     * @author Tiger <1192851302@qq.com>
     * @param Request $request
     * @return type
     */
    public function reset_password(Request $request) {
        [$account, $vercode, $password, $repassword] = UtilService::postMore([
                    'account',
                    'vercode',
                    'password',
                    'repassword'
                        ], $request, true);
        $verifyCode = Cache::get('code_' . $account);
        if (empty($verifyCode)) {
            return app('json')->fail('请先获取验证码');
        }
        if (substr($verifyCode, 0, 6) != $vercode) {
            return app('json')->fail('验证码错误');
        }

        $validate = new AdminUserValidate();
        if ($validate->scene('forget')->check(compact('password', 'repassword')) == false) {
            return app('json')->fail($validate->getError());
        }
        $salt = create_salt();
        try {
            AdminUser::update([
                'password' => encrypt_password($password, $salt),
                'salt' => $salt
                    ], [
                'mobile' => $account
            ]);
        } catch (\Exception $exc) {
            return app('json')->fail($exc->getMessage());
        }
        return app('json')->successful('重置密码成功');
    }

}
